/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package drexel.cs544.nap.server;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Vector;
import org.apache.log4j.Logger;
import org.xml.sax.SAXException;

import drexel.cs544.nap.NAP;
import drexel.cs544.nap.log.LoggerSetup;
import drexel.cs544.nap.server.xml.GroupLoader;
import java.io.File;
import java.net.URL;

/**
 *
 * @author rch_ltp
 */
public class NAPServer {

    private static final int PORT_NUMBER = 5440;
    private static NAPServer _instance;
    private Vector<ClientNode> _vClients;
    private Vector<Group> _groups;
    private int _nextGroup = 0;

    public NAPServer() {
        _vClients = new Vector<ClientNode>();
        _groups = new Vector<Group>();
        try {
            URL urlXML = getClass().getResource("GroupConfiguration.xml"); 
            File fXML = new File(urlXML.toURI());
            _groups = GroupLoader.getInstance().parse(fXML);

        } catch (Exception e) {
            Logger.getLogger(NAPServer.class).error("Could not find or parse XML", e);
        } 
    }

    public static NAPServer getInstance() {
        if (_instance == null) {
            _instance = new NAPServer();
        }
        return _instance;
    }

    public void start() throws Exception {
        //i need to handle single nodes, groups of nodes
        ServerSocket ssNAP = new ServerSocket(PORT_NUMBER);
        boolean isAlive = true;

        while (isAlive) {
            //keep connection going, each time a new request comes in, spawn a
            //new protocol thread to handle the connection
            Logger.getLogger(NAPServer.class).info("Waiting for connection...");
            Socket sClient = ssNAP.accept(); //client connection
            NAPServerThread nstThread = new NAPServerThread(sClient);
            Logger.getLogger(NAPServer.class).info("Connection established to " + sClient.toString());
            nstThread.start();
        }
    }

    public void addClient(ClientNode cn) {
        _vClients.add(cn);
    }

    public boolean containsClient(ClientNode cn) {
        return _vClients.contains(cn);
    } 

    public Group getNextGroup() {
        Group nextGroup = _groups.get(_nextGroup);
        _nextGroup = _groups.size() - 1 == _nextGroup ? 0 : _nextGroup + 1;
        return nextGroup;
    }
}
